#ifndef __MOUSECURSOR_H__
#define __MOUSECURSOR_H__

#include <OgrePanelOverlayElement.h>

using namespace Ogre;

class MouseCursor
{
private:
    Overlay* mGuiOverlay;
    OverlayContainer* mCursorContainer;
    TexturePtr mTexture;
	//TexturePtr mTexture_Crosshair;
    MaterialPtr mMaterial_Mouse;
	//MaterialPtr mMaterial_Crosshair;

	Ogre::Real xloc;
	Ogre::Real yloc;

    Real mWindowWidth;
    Real mWindowHeight;

public:
    MouseCursor(): mGuiOverlay(0), mCursorContainer(0)
    {
        mMaterial_Mouse = MaterialManager::getSingleton().getByName("MouseCursor/MouseCursor");
		//mMaterial_Crosshair = MaterialManager::getSingleton().getByName("MouseCursor/CrosshairCursor");
        
		mCursorContainer = (OverlayContainer*) OverlayManager::getSingletonPtr()->createOverlayElement("Panel", "MouseCursor");
        mCursorContainer->setMaterialName(mMaterial_Mouse->getName());
        mCursorContainer->setPosition(0.0f,0.0f);

        mGuiOverlay = OverlayManager::getSingletonPtr()->create("MouseCursor");
        mGuiOverlay->setZOrder(649);
        mGuiOverlay->add2D(mCursorContainer);
        mGuiOverlay->show();

		setImage();
    }

    ~MouseCursor(void) {}

	void setImage(/*const String& filename*/)
    {
		// Setup mouse cursor
        TextureUnitState *pTexState;
		if(mMaterial_Mouse->getTechnique(0)->getPass(0)->getNumTextureUnitStates())
        {
			pTexState = mMaterial_Mouse->getTechnique(0)->getPass(0)->getTextureUnitState(0);
			pTexState->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);

			mTexture = static_cast<Ogre::TexturePtr>(TextureManager::getSingletonPtr()->getByName(pTexState->getTextureName()));
			if (mTexture.isNull())
				mTexture = TextureManager::getSingletonPtr()->load(pTexState->getTextureName(), "Plitzkrieg");

			mMaterial_Mouse->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
        }

		// Setup crosshair cursor
		/*pTexState = 0;
		if(mMaterial_Crosshair->getTechnique(0)->getPass(0)->getNumTextureUnitStates())
        {
			pTexState = mMaterial_Crosshair->getTechnique(0)->getPass(0)->getTextureUnitState(0);
			pTexState->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);

			mTexture = static_cast<Ogre::TexturePtr>(TextureManager::getSingletonPtr()->getByName(pTexState->getTextureName()));
			if (mTexture.isNull())
				mTexture = TextureManager::getSingletonPtr()->load(pTexState->getTextureName(), "Plitzkrieg");

			mMaterial_Crosshair->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
        }*/
    }

    void setWindowDimensions(unsigned int width, unsigned int height) {
        mWindowWidth = (width > 0) ? width : 1;
        mWindowHeight = (height > 0) ? height : 1;
		// Note: make all cursors 32x32 den no need to worry
        mCursorContainer->setWidth(mTexture->getWidth() / mWindowWidth);
        mCursorContainer->setHeight(mTexture->getHeight() / mWindowHeight);
    }

    void setVisible(bool visible)
    {
        if(visible) {
            mCursorContainer->show();
        } else {
            mCursorContainer->hide();
        }
    }

    void updatePosition(int x, int y)
    {
        xloc = x / mWindowWidth;
        yloc = y / mWindowHeight;
        mCursorContainer->setPosition(clamp(xloc, 0.0f, 1.0f), clamp(yloc, 0.0f, 1.0f));
    }

	Ogre::Real getX() { return clamp(xloc, 0.0f, 1.0f); }
	Ogre::Real getY() { return clamp(yloc, 0.0f, 1.0f); }

    Real clamp(Real a, Real min, Real max) {
        if (a < min) {
            return min;
        }
        if (a > max) {
            return max;
        } 
        return a;
    }

	//void useMouse() { mCursorContainer->setMaterialName(mMaterial_Mouse->getName()); }
	//void useCrosshair() { mCursorContainer->setMaterialName(mMaterial_Crosshair->getName()); }
};

#endif
